class AuthD::Request
	IPC::JSON.message CheckPermission, 10 do
		property user       : UserID? = nil
		property service    : String
		property resource   : String

		def initialize(@user, @service, @resource)
		end

		def to_s(io : IO)
			super io
			io << " (user: #{@user}, service: #{@service}, resource: #{@resource})"
		end

		def handle(authd : AuthD::Service, fd : Int32)
			logged_user = authd.get_logged_user_full? fd
			return Response::ErrorMustBeAuthenticated.new if logged_user.nil?

			user = if u = @user
				logged_user.assert_permission("authd", "*", User::PermissionLevel::Read)
				authd.user? u
			else
				logged_user
			end
			return Response::ErrorUserNotFound.new if user.nil?

			service_permissions = user.permissions[@service]?
			resource_permissions = if service_permissions.nil?
				User::PermissionLevel::None
			elsif p = service_permissions[@resource]?
				p
			else
				User::PermissionLevel::None
			end

			return Response::PermissionCheck.new @service, @resource, user.uid, resource_permissions
		end
	end
	AuthD.requests << CheckPermission

	IPC::JSON.message SetPermission, 11 do
		property user       : UserID
		property service    : String
		property resource   : String
		property permission : ::AuthD::User::PermissionLevel

		def initialize(@user, @service, @resource, @permission)
		end

		def to_s(io : IO)
			super io
			io << " (user: #{@user}, service: #{@service}, resource: #{@resource}, permission: #{@permission})"
		end

		def handle(authd : AuthD::Service, fd : Int32)
			logged_user = authd.get_logged_user_full? fd
			return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
			logged_user.assert_permission("authd", "*", User::PermissionLevel::Admin)

			user = if u = @user
				authd.user? u
			else
				logged_user
			end
			return Response::ErrorUserNotFound.new if user.nil?

			service_permissions = user.permissions[@service]?

			if service_permissions.nil?
				service_permissions = Hash(String, User::PermissionLevel).new
				user.permissions[@service] = service_permissions
			end

			if @permission.none?
				service_permissions.delete @resource
			else
				service_permissions[@resource] = @permission
			end

			authd.users_per_uid.update user.uid.to_s, user

			Response::PermissionSet.new user.uid, @service, @resource, @permission
		end
	end
	AuthD.requests << SetPermission
end
